package com.cube.dp.cor.context;

import com.cube.dp.base.utils.IpUtil;
import lombok.*;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author poker.li
 * @date 2021/12/13 16:58
 * <p>
 * 短链上下文
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuppressWarnings("unused")
@ToString
public class TransformContext {


    /**
     * 短链code,根据该code找到原始链接
     */
    @NonNull
    private String shortUrlCode;

    /**
     * 原始长链接
     */
    private String originLongUrl;

    /**
     * 客户端ip
     */
    @NonNull
    private String ip;

    /**
     * 客户端主机名
     */
    private String hostName;

    /**
     * 短链请求头
     */
    private Map<String, String> headers = new HashMap<>(4);

    /**
     * 短链请求上下文中封装的参数
     */
    private Map<String, Object> params = new HashMap<>(4);

    @Nullable
    private Cookie[] cookies;

    /**
     * 短链转换状态
     */
    private TransformStatus transformStatus;

    public String getShortUrlCode() {
        return shortUrlCode;
    }

    public void setShortUrlCode(String shortUrlCode) {
        this.shortUrlCode = shortUrlCode;
    }

    public Map<String, String> getHeaders() {
        return headers;
    }

    public void setHeaders(Map<String, String> headers) {
        this.headers = headers;
    }

    public Map<String, Object> getParams() {
        return params;
    }

    public <T> T getParam(String key) {
        Object param = params.get(key);
        if (param == null) {
            return null;
        }
        //noinspection unchecked
        return (T) param;
    }

    public void setParams(Map<String, Object> params) {
        this.params = params;
    }

    public TransformStatus getTransformStatus() {
        return transformStatus;
    }

    public void setTransformStatus(TransformStatus transformStatus) {
        this.transformStatus = transformStatus;
    }

    @NonNull
    public String getIp() {
        return ip;
    }

    public void setIp(@NonNull String ip) {
        this.ip = ip;
    }

    @Nullable
    public Cookie[] getCookies() {
        return cookies;
    }

    public void setCookies(@Nullable Cookie[] cookies) {
        this.cookies = cookies;
    }

    public void release() {
        headers = null;
        params = null;
    }

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
    }

    public void setHeader(String key, String value) {
        this.headers.put(key, value);
    }

    public String getOriginLongUrl() {
        return originLongUrl;
    }

    public void setOriginLongUrl(String originLongUrl) {
        this.originLongUrl = originLongUrl;
    }

    public static TransformContext of(@NonNull HttpServletRequest request, @NonNull String shortUrlCode) {
        Assert.notNull(request, "HttpServletRequest must not be null");
        TransformContext context = new TransformContext();
        context.setIp(IpUtil.getIpAddress(request));
        context.setCookies(request.getCookies());
        context.setHostName(request.getRemoteHost());
        context.setShortUrlCode(shortUrlCode);

        Enumeration<String> headerNames = request.getHeaderNames();

        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String headerName = headerNames.nextElement();
                String headerValue = request.getHeader(headerName);
                context.setHeader(headerName, headerValue);
            }
        }
        return context;
    }
}
